package server

import (
	"fmt"
	consulapi "github.com/hashicorp/consul/api"
	"net"
	"strconv"
)

type RegisterCenterTool struct {
}

type ConsulRegisterConfig struct {
	ConsulAddress       string
	ServiceName         string
	ServiceHost         string
	ServicePort         int
	ServiceTags         []string
	HealthCheckInterval string
	HealthCheckUrl      string
}

type ConsulServiceFindConfig struct {
	ConsulAddress string
	ServiceName   string
	ServiceTag    string
}

func (registerCenterTool *RegisterCenterTool) RegisterToConsul(registerConfig ConsulRegisterConfig) error {
	config := consulapi.DefaultConfig()
	config.Address = registerConfig.ConsulAddress //consul地址
	reg := consulapi.AgentServiceRegistration{}
	reg.Name = registerConfig.ServiceName    //注册service的名字
	reg.Address = registerConfig.ServiceHost //注册service的ip
	reg.Port = registerConfig.ServicePort    //注册service的端口
	reg.Tags = registerConfig.ServiceTags

	check := consulapi.AgentServiceCheck{}              //创建consul的检查器
	check.Interval = registerConfig.HealthCheckInterval //设置consul心跳检查时间间隔
	check.HTTP = registerConfig.HealthCheckUrl          //设置检查使用的url

	reg.Check = &check

	client, err := consulapi.NewClient(config) //创建客户端
	if err != nil {
		//log.Fatal(err)
	}
	err = client.Agent().ServiceRegister(&reg)
	if err != nil {
		return err
	}
	return nil
}

func (registerCenterTool *RegisterCenterTool) FindServiceFromConsul(consulServiceConfig ConsulServiceFindConfig) ([]*consulapi.ServiceEntry, *consulapi.QueryMeta, error) {
	var lastIndex uint64
	config := consulapi.DefaultConfig()
	config.Address = consulServiceConfig.ConsulAddress //consul server

	client, err := consulapi.NewClient(config)
	if err != nil {
		fmt.Println("api new client is failed, err:", err)
		return []*consulapi.ServiceEntry{&consulapi.ServiceEntry{}}, &consulapi.QueryMeta{}, err
	}
	services, metainfo, err := client.Health().Service(consulServiceConfig.ServiceName, consulServiceConfig.ServiceTag, true, &consulapi.QueryOptions{
		WaitIndex: lastIndex, // 同步点，这个调用将一直阻塞，直到有新的更新
	})
	if err != nil {
		fmt.Errorf("error retrieving instances from Consul: %v", err)
		return []*consulapi.ServiceEntry{&consulapi.ServiceEntry{}}, &consulapi.QueryMeta{}, err
	}
	lastIndex = metainfo.LastIndex

	addrs := map[string]struct{}{}
	for _, service := range services {
		fmt.Println("service.Service.Address:", service.Service.Address, "service.Service.Port:", service.Service.Port)
		addrs[net.JoinHostPort(service.Service.Address, strconv.Itoa(service.Service.Port))] = struct{}{}
	}
	return services, metainfo, err
}
